import axios from 'axios';
import {Message} from 'element-ui';
import {serialize} from './util'
import {getTokenInCookie} from './auth'
import router from '@/router/'
import store from '@/store/';
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style

const ReqMethod = {
  GET: 'get',
  POST: 'post',
  PUT: 'put',
  DELETE: 'delete',
};

const ContentType = {
  JSON: 'application/json;charset=utf-8',
  FORM_URLENCODED: 'application/x-www-form-urlencoded;charset=utf-8',
};

let instance = axios.create({
  timeout: 20000,
  headers: {
    'X-Requested-With': 'XMLHttpRequest',
    'Content-Type': ContentType.JSON,
  },
  withCredentials: false
});

// NProgress Configuration
NProgress.configure({
  showSpinner: false
});

// 请求前拦截
instance.interceptors.request.use(
  config => {
    // start progress bar
    NProgress.start();
    const meta = (config.meta || {});
    let tokenInCookie = getTokenInCookie();
    if (tokenInCookie) {
      config.headers['Authorization'] = tokenInCookie;
    }
    //headers中配置serialize为true开启序列化
    if (config.method === ReqMethod.POST && meta.isSerialize) {
      config.data = serialize(config.data);
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 返回后拦截
instance.interceptors.response.use(
  data => {
    NProgress.done();
    if (data.data.status === 200) {
      return data.data
    } else {
      Message.error({message: data.data.message})
      return data.data
    }
  },
  err => {
    NProgress.done();
    if (err.response) {
      if (err.response.status === 400) {
        Message.error({message: err.response.data.message})
      } else if (err.response.status === 504 || err.response.status === 404) {
        Message.error({message: '服务器被吃了⊙﹏⊙∥'})
      } else if (err.response.status === 401) {
        Message.error({message: '登录信息失效，请重新登录'});
        store.dispatch('FedLogOut').then(() => router.push('/login'));
        // window.location.href = window.location.href.replace(/#\/.*/, '#/login');
        // window.location.href = location.protocol + '//' + location.host + '/#/login';
      } else if (err.response.status === 500) {
        Message.error({message: '服务器开小差了⊙﹏⊙∥'})
      } else {
        Message.error({message: '网络不给力，请稍后再试'})
      }
    } else {
      Message.error({message: '网络不给力，请稍后再试'})
    }
    return Promise.reject(err)
  }
);

let base = '';

const postJSON = (url, params) => {
  return httpRequest(ReqMethod.POST, url, params, ContentType.JSON);
};

const postQuery = (url, params) => {
  return httpRequest(ReqMethod.POST, `${url}${bodyToParam(params)}`, params, ContentType.FORM_URLENCODED);
};

const postRequest = (url, params) => {
  return httpRequest(ReqMethod.POST, url, params, ContentType.FORM_URLENCODED);
};

const putRequest = (url, params) => {
  return httpRequest(ReqMethod.PUT, url, params, ContentType.JSON);
};

const deleteRequest = (url, params) => {
  return httpRequest(ReqMethod.DELETE, `${url}${bodyToParam(params)}`, params);
};

const getRequest = (url, params) => {
  return httpRequest(ReqMethod.GET, url, `${url}${bodyToParam(params)}`, params);
};

/**
 * 基础请求封装
 * @param method 请求方式
 * @param url  请求URL
 * @param data 请求数据
 * @param contentType 媒体类型
 * @returns {AxiosPromise<any>}
 */
const httpRequest = (method, url, data, contentType) => {
  return instance.request({
    method: method,
    url: `${base}${paddingToPath(url, data)}`,
    data: data,
    headers: {
      'Content-Type': contentType,
    }
  })
};

const multipleRequest = function (requestArray, callback) {
  axios.all(requestArray).then(axios.spread(callback))
};

/**
 * url占位符填充
 * @param url 请求url
 * @param pathParam path参数
 * @param data body参数
 */
function paddingToPath(url, pathParam, data) {
  let reqUrl = url;
  if (reqUrl) {
    let startIndex = reqUrl.indexOf('{');
    let endIndex = reqUrl.indexOf('}');
    if (startIndex > 0 && endIndex > 0) {
      let param = reqUrl.substring(startIndex + 1, endIndex);
      let value = pathParam[param] || data[param];
      if (!value) {
        throw new Error('url path parse error!!!');
      }
      reqUrl = reqUrl.replace(`{${param}}`, value);
      reqUrl = paddingToPath(reqUrl, pathParam, data);
    }
  }
  return reqUrl;
}

// 对象型参数转param型参数
function bodyToParam(body, head, oldParam) {
  let param = '';
  let newHead = '';
  if (head) {
    newHead = head;
  }
  if (oldParam) {
    param = oldParam;
  }
  if (undefined !== body) {
    let flag = 0;
    if (param) {
      flag = 1;
    }
    for (let i in body) {
      if (undefined !== body[i]) {
        if ((typeof body[i]) === 'string') {
          body[i] = body[i].trim();
        }
        if (flag === 0) {
          if (body[i] instanceof Object) {
            param = bodyToParam(body[i], `${newHead}${i}.`, param);
          } else {
            param = `?${newHead}${i}=${encodeURIComponent(body[i])}`;
          }
          if (param) {
            flag = 1;
          }
        } else {
          if (body[i] instanceof Object) {
            param = bodyToParam(body[i], `${newHead}${i}.`, param);
          } else {
            param = `${param}&${newHead}${i}=${encodeURIComponent(body[i])}`;
          }
        }
      }
    }
  }
  return param;
}

export {getRequest, postRequest, postJSON, postQuery, putRequest, deleteRequest, multipleRequest}
